package gotnames.web.st;

import gotnames.dm.KTrans;
import gotnames.dm.ProfilePicture;
import gotnames.dm.ProfilePictureData;
import gotnames.dm.QueryBuilder;
import gotnames.dm.User;
import gotnames.web.Facebook;
import gotnames.web.GotNamesServlet.UserAuthenticator;

import java.io.IOException;
import java.net.URL;

import javax.jdo.PersistenceManager;

import org.apache.commons.io.IOUtils;

import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.OutputSettings;
import com.google.appengine.api.images.Transform;
import com.google.appengine.api.images.ImagesService.OutputEncoding;
import com.google.appengine.repackaged.org.json.JSONException;
import com.medallia.spider.RenderTask;
import com.medallia.tiny.Strings;

/**
 * After the user selects a picture using {@link FacebookProfilePicTask} this
 * task allows them to crop the picture before using it as their Got Names
 * profile picture.
 */
public class FacebookCropPhotoTask extends RenderTask {
	
	@Input interface Params {
		String selectedPhoto();
		
		String crop();
		int x1();
		int y1();
		int x2();
		int y2();
		String submit();
	}
	
	@Output interface Values {
		V<String> PHOTO_ID = v();
		V<String> PHOTO_URL = v();
	}
	
	PostAction action(final User user, Params p, Facebook fb, PersistenceManager pm, UserAuthenticator userAuthenticator) throws JSONException, IOException {
		String selectedPhoto = p.selectedPhoto();
		if (selectedPhoto == null)
			return rawStringUtf8("Missing argument");
		
		String selectedPhotoUrl = fb.query(selectedPhoto).getString("source");
		
		if (p.submit() != null) {
			// fetch image url
			URL imageUrl = new URL(selectedPhotoUrl); 
			byte[] imageBytes = IOUtils.toByteArray(imageUrl.openStream());
			
			// Convert to image to make sure it is valid
			Image image = ImagesServiceFactory.makeImage(imageBytes);
			
			// Crop if necessary
			if (Strings.hasContent(p.crop())) {
				if (p.x2() - p.x1() > 10 && p.y2() - p.y1() > 10) {
					double xs = image.getWidth();
					double ys = image.getHeight();
					Transform crop = ImagesServiceFactory.makeCrop(p.x1() / xs, p.y1() / ys, p.x2() / xs, p.y2() / ys);
					
					OutputSettings jpeg = new OutputSettings(OutputEncoding.JPEG);
					image = ImagesServiceFactory.getImagesService().applyTransform(crop, image, jpeg);
				}
			}
			
			final ProfilePictureData profilePicture = ProfilePictureData.getProfilePicture(image.getImageData());
			ProfilePicture.saveProfilePicture(user, pm, profilePicture);
			
			userAuthenticator.userUpdated(new KTrans<User>(pm) {
				@Override protected User call() {
	 				User u = QueryBuilder.begin(pm, User.class).getSingleByKey(user.getKey());
	 				u.setProfilePictureInfo(profilePicture);
	 				return u;
				}
			}.go());
			
			return redirectToTask(EditProfileTask.class);
		} else {
			// Allow the user to crop
			attr(Values.PHOTO_ID, selectedPhoto);
			attr(Values.PHOTO_URL, selectedPhotoUrl);
			
			return null;
		}
	}
	
	@Override public String getPageTitle() { return "Crop photo"; }

}
